home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 331_01 / search.c < prev    next >
Text File  |  1990-06-12  |  15KB  |  535 lines

  1. /*
  2. HEADER:         CUG999.04;
  3. TITLE:          GED (nee QED) screen editor -- part 4;
  4. DATE:           10/08/86;
  5.  
  6. DESCRIPTION:    "Find, alter, and repeat commands for the GED editor.";
  7. KEYWORDS:       find, alter, repeat, pattern matching, search, replace;
  8. FILENAME:       GED4.C;
  9. AUTHORS:        G. Nigel Gilbert, James W. Haefner, Mel Tearle, G. Osborn;
  10. COMPILERS:      DeSmet C;
  11. */
  12.  
  13. /*
  14.      e/qed/ged  screen editor
  15.  
  16.     (C) G. Nigel Gilbert, MICROLOGY, 1981
  17.            August-December 1981
  18.  
  19.     Modified:  Aug-Dec   1984:   BDS-C 'e'(vers 4.6a) to 'qe' (J.W. Haefner)
  20.                March     1985:   BDS-C 'qe' to DeSmet-C 'qed' (J.W. Haefner)
  21.                May       1986:   converted to ged - Mel Tearle
  22.  
  23.     FILE:      ged4.c
  24.  
  25.     FUNCTIONS: info, findorrep, dofindrep, find
  26.  
  27.     PURPOSE:   perform find, alter and repeat commands
  28.  
  29. */
  30.  
  31.  
  32. #include <stdio.h>
  33. #include "ged.h"
  34.  
  35. /* ^Q quick key services */
  36.  
  37. char spatt[81];
  38. char changeto[81];
  39.  
  40. info()
  41. {
  42.     unsigned char c;
  43.  
  44.     puttext();
  45.     putmess("|F|ind, |A|lter, |K|ontext/files, |P|aragraph");
  46.     while ( (c = getlow()) != 'a' && c != 'f' && c != 'k' &&
  47.         c != 'p' && c != ESCKEY );
  48.     if (c == ESCKEY)
  49.         return;
  50.     switch (c)  {
  51.     case 'f':
  52.         findorrep(0);
  53.         break;
  54.     case 'a':
  55.         findorrep(1);
  56.         break;
  57. /* the wordstar ^QY clear to end of line command.  disabled here because
  58.  * this version uses ^Y to delete from cursor to end of line
  59.  *
  60.  *  case 'y':
  61.  *      cleareol(cursorx,cursory);
  62.  *      altered = YES;
  63.  *      text[charn] = '\0';
  64.  *      break;
  65.  */
  66.     case 'k':
  67.         envir();
  68.         break;
  69.     case 'p':
  70.         putmess("(F1 = dot help)  Delete dot commands while reforming?  (Y/N)");
  71.         while ( (c = getlow()) != 'y' && c != 'n' && c != ESCKEY && c != F1KEY);
  72.         if (c == ESCKEY)
  73.             return;
  74.         if (c == F1KEY) {
  75.             helpdot();
  76.             return;
  77.         }
  78.         if (c == 'y')
  79.             roff(0);
  80.         else
  81.             roff(1);
  82.         break;
  83.     }
  84. }
  85.  
  86.  
  87. /* initiate string search or search and replace.  Called by F2 key
  88.  * with mode = 0 or from above.
  89.  * F2 str F3  search back
  90.  * F2 str F4  search fwd
  91.  * F2 str1 F2 str2 F3 replace backward
  92.  * F2 str1 F2 str2 F4 replace forward
  93.  * F3 & F4 & ^L  resume
  94.  */
  95. findorrep(mode)
  96. int mode;
  97. {
  98.     int i, cnt;
  99.     int c;
  100.     char tpat[80];
  101.     puttext();
  102.  
  103.     putmess("|Find|? ");
  104.     c = scans(tpat,80);
  105.     if ( c == ESCKEY || !tpat[0] )
  106.         return;
  107.     strcpy(spatt, tpat);  /* move valid string to permanent storage */
  108.     if (c == F2KEY)
  109.         replace = YES;
  110.     else
  111.         replace = mode;
  112.  
  113.     if ( replace )  {
  114.         putmess("Alter to? ");
  115.         c = scans(changeto,80);  /* null replacemente allowed */
  116.         if (!ctrl) {
  117.             if (c == ESCKEY)
  118.                 return;     /* no escape if <esc> can be embedded */
  119.             for (i = 0; (changeto[i]); i++) {
  120.                 if (changeto[i] < ' ') {
  121.                     error("Use -C option to embed ctrl codes (F7)");
  122.                     return;
  123.                 }
  124.             }
  125.         }
  126.     }
  127.     else {
  128.         changeto[0] = '\0';
  129.     }
  130.  
  131. /* Global is the only option because this would be an awkward way to
  132.  * replace one word.
  133.  * To do the entire document it is necessary to use the <home> key first
  134.  * to jump to line 1.
  135.  * It is planned to add a wrap at end of file option, probably as the default.
  136.  */
  137.  
  138. /*defaults */
  139.     nocheck = NO;
  140.     cnt  = 0;
  141.     findir = 1;
  142.  
  143.     if ( c == F3KEY) {
  144.         findir = -1;
  145.     }
  146.     else if (c == F4KEY) {
  147.         findir = 1;
  148.     }
  149. /* string terminated by <ret> */
  150.     else {
  151.         if ( replace )
  152.             putmess("|B|ackward,  |W|ithout asking, |count| ");
  153.         else
  154.             putmess("|<ret>|, |B|ackwards, |count| ");
  155.         if ( scans(opts,5) == ESCKEY )
  156.             return;
  157.  
  158.         for ( i = 0; ( c = opts[i]); i++ )  {
  159.             switch(tolower(c)) {
  160.             case 'b':
  161.                 findir = -1;
  162.                 break;
  163.             case 'w':
  164.                 nocheck = YES;
  165.                 break;
  166.             default:
  167.                 if ( c >= '0' && c <= '9' )
  168.                     cnt = cnt*10+c-'0';
  169.             }
  170.         }
  171.     }
  172.     if ( cnt == 0 )  {
  173.         if (replace)
  174.             cnt = -1; /* unlimited */
  175.         else
  176.             cnt = 1;
  177.     }
  178.     dofindrep(cnt,findir);
  179. }
  180.  
  181.  
  182.  
  183. /* Resume a search or search and replace
  184.  * Called by F4, F5, ^L, and from above.
  185.  * All searchs and search/replace operations wrap at beginning and end of file.
  186.  * The first possible match is the first char beyond
  187.  * the cursor position.  The last possible match is at the initial
  188.  * cursor position.
  189.  */
  190. int ncline, count, oldlen, newlen;
  191.  
  192. dofindrep(count1,dir)
  193. int count1,dir;
  194. {
  195.     int i, j, l2, s0, ocharn, ocline, ncharn;
  196.     char c;
  197.     char buf[81+35];
  198.  
  199.  
  200.     puttext();
  201.     count = count1;
  202.     findir = dir;  /* F2 and F3 keys permanently change directin */
  203.     oldlen = strlen(spatt);
  204.     ocline = cline;
  205.     ncline = cline;
  206.     ocharn = charn;
  207.     ncharn = charn;
  208.     if (findir > 0) {
  209.         newlen = 1;    /* don't start at the cursor */
  210.  
  211.         putmess1("    ", 28, 5);
  212.         while (i = find(charn+newlen, cline, LLIM, lastl)) {
  213.             if (i < 0)
  214.                 return;
  215.             if (!dorep())
  216.                 return;
  217.             ncline = cline;
  218.             ncharn = charn;
  219.         }
  220.         putmess1("EOF", 28, 5);
  221.         wait(1);
  222.         puttext();
  223.         charn = newlen = 0;
  224.         cline = 1;
  225.         plast = -1;
  226.         gettext(cline, 0);
  227.         while (i = find(charn+newlen, cline, ocharn, ocline)) {
  228.             if (i < 0)
  229.                 return;
  230.             s0 = strlen(text);
  231.             if (!dorep())
  232.                 return;
  233.             if (cline == ocline)
  234.                 ocharn += strlen(text) - s0;
  235.             ncline = cline;
  236.             ncharn = charn;
  237.         }
  238.     }
  239.     else {
  240.         s0 = strlen(text);
  241.         while (i = find(charn-1, cline, 0, cline)) {
  242.             if (i < 0)
  243.                 return;
  244.             if (!dorep())
  245.                 return;
  246.             ncline = cline;
  247.             ncharn = charn;
  248.         }
  249.         ocharn += strlen(text) - s0; /* terminal point changes with replacemets */
  250.         charn = 0;
  251.         putmess1("    ", 28, 5);
  252.         while (i = find(charn-1, cline, 0, 1)) {
  253.             if (i < 0)
  254.                 return;
  255.             if (!dorep())
  256.                 return;
  257.             ncline = cline;
  258.             ncharn = charn;
  259.         }
  260.         puttext();
  261.         putmess1("BOF", 28, 5);
  262.         wait(1);
  263.         cline = lastl;
  264.         plast = -1;
  265.         gettext(cline, 0);
  266.         charn=strlen(text);
  267.         while (i = find(charn-1, cline, ocharn, ocline)) {
  268.             if (i < 0) {
  269.                 return;
  270.             }
  271.             if (!dorep())
  272.                 return;
  273.             ncline = cline;
  274.             ncharn = charn;
  275.         }
  276.     }
  277.     strcpy(buf,"Search for '");
  278.     strcat(buf,spatt);
  279.     strcat(buf,"' fails");
  280.     error1(buf);
  281.     wait(2);
  282.     putstatusline(ncline);
  283.     charn = ncharn;
  284.     moveline(ncline-cline);
  285.     curson(YES);
  286.     return;
  287. }
  288.  
  289. int dorep()
  290. {
  291.     int i, j;
  292.     char c;
  293.  
  294.     if (!replace)
  295.         return 0;
  296.  
  297.  
  298.     if ( nocheck )
  299.         c = 'y';
  300.     else  {
  301.         blankedmess = YES;
  302.         putlineno(cline);
  303.         putmess1("Replace  |<esc>|/|Y|/|N| ?", 34, 37);
  304.         do {
  305.             gotoxy(55,0);  /* position just after prompt */
  306.             for (i=0; i < 3000; i++);
  307.             resetpcursor();
  308.             for (i=0; i < 3000; i++);
  309.         }
  310.         while (chkbuf() == 0);
  311.  
  312.         c = testlow();
  313.     }
  314.     switch(c)  {
  315.     case 'y' :
  316.         newlen = strlen(changeto);   /* null replacement allowed */
  317.         if ( strlen(text) + newlen - oldlen + 1 > LLIM )  {
  318.             error(" Line would be too long ");
  319.             return;
  320.         }
  321. /* delete the old word */
  322.         for ( j = charn; (text[j] = text[j + oldl